package com.wzgl.core.config.plugin;

import java.util.List;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.StdSchedulerFactory;

import com.jfinal.plugin.IPlugin;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.redis.Redis;
import com.jfinal.template.stat.ParseException;
import com.wzgl.core.CacheConsts;
import com.wzgl.core.model.Tmagic;
import com.wzgl.core.utils.WZGLUtils;

public class QuartzManager implements IPlugin{
	private static SchedulerFactory gSchedulerFactory = new StdSchedulerFactory();  
    private static String JOB_GROUP_NAME = "EXTJWEB_JOBGROUP_NAME";  
    private static String TRIGGER_GROUP_NAME = "EXTJWEB_TRIGGERGROUP_NAME";  
    //游戏任务
    private static String JOB_GROUP_GAME = "JOB_GROUP_GAME"; 
    private static String TRIGGER_GROUP_GAME_NAME = "TRIGGER_GROUP_GAME_NAME";  
    /** 
     * 添加一个定时任务，使用默认的任务组名，触发器名，触发器组名 
     * 
     * @param jobName 
     *            任务名 
     * @param jobClass 
     *            任务 
     * @param time 
     *            时间设置，参考quartz说明文档 
     * @throws SchedulerException 
     * @throws ParseException 
     */  
    @SuppressWarnings("unchecked")
	public static void addJob(String jobName, String jobClass, String time) {  
        try {  
            Scheduler sched = gSchedulerFactory.getScheduler();  
            JobDetail jobIns = JobBuilder.newJob((Class<? extends Job>) Class.forName(jobClass)).withIdentity(jobName,JOB_GROUP_NAME).build();
            
            CronScheduleBuilder builder = CronScheduleBuilder.cronSchedule(time);
            //创建Trigger  触发器
            Trigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, TRIGGER_GROUP_NAME).startNow()
            		.withSchedule(builder).build();
            
            //调度执行
            sched.scheduleJob(jobIns, trigger);
            // 启动  
            if (!sched.isShutdown()){  
                sched.start();  
            }  
        } catch (Exception e) {  
            e.printStackTrace();  
            throw new RuntimeException(e);  
        }  
    }  
  
    /** 
     * 添加一个定时任务 
     * 
     * @param jobName 
     *            任务名 
     * @param jobGroupName 
     *            任务组名 
     * @param triggerName 
     *            触发器名 
     * @param triggerGroupName 
     *            触发器组名 
     * @param jobClass 
     *            任务 
     * @param time 
     *            时间设置，参考quartz说明文档 
     * @throws SchedulerException 
     * @throws ParseException 
     */  
    public static void addJob(String jobName, String jobGroupName,  
            String triggerName, String triggerGroupName, String jobClass, String time){  
        try {  
        	 Scheduler sched = gSchedulerFactory.getScheduler();  
             JobDetail jobIns = JobBuilder.newJob((Class<? extends Job>) Class.forName(jobClass)).withIdentity(jobName,jobGroupName).build();
             
             CronScheduleBuilder builder = CronScheduleBuilder.cronSchedule(time);
             //创建Trigger
             Trigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerName, triggerGroupName).startNow()
             		.withSchedule(builder).build();
             
             //调度执行
             sched.scheduleJob(jobIns, trigger);
             // 启动  
             if (!sched.isShutdown()){  
                 sched.start();  
             }  
        } catch (Exception e) {  
            e.printStackTrace();  
            throw new RuntimeException(e);  
        }  
    }  
  
    /** 
     * 修改一个任务的触发时间(使用默认的任务组名，触发器名，触发器组名) 
     * 
     * @param jobName 
     * @param time 
     */  
    public static void modifyJobTime(String jobName, String time) {  
        try {  
            Scheduler sched = gSchedulerFactory.getScheduler();  
            TriggerKey triggerKey = TriggerKey.triggerKey(jobName,TRIGGER_GROUP_NAME);
            CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerKey);
            
            if(trigger == null) {  
                return;  
            }  
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(time);
            String oldTime = trigger.getCronExpression();  
            if (!oldTime.equalsIgnoreCase(time)) {  
            	trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
            		    .withSchedule(scheduleBuilder).build();
            	sched.rescheduleJob(triggerKey, trigger); 
            }  
        } catch (Exception e) {  
            e.printStackTrace();  
            throw new RuntimeException(e);  
        }  
    }  
  
    /** 
     * 修改一个任务的触发时间 
     * 
     * @param triggerName 
     * @param triggerGroupName 
     * @param time 
     */  
    public static void modifyJobTime(String triggerName,  
            String triggerGroupName, String time) {  
        try {  
        	Scheduler sched = gSchedulerFactory.getScheduler();  
            TriggerKey triggerKey = TriggerKey.triggerKey(triggerName,triggerGroupName);
            CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerKey);
            if(trigger == null) {  
                return;  
            }  
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(time);
            String oldTime = trigger.getCronExpression();  
            if (!oldTime.equalsIgnoreCase(time)) {  
            	trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
            		    .withSchedule(scheduleBuilder).build();
            	sched.resumeTrigger(triggerKey);  
            }  
        } catch (Exception e) {  
            e.printStackTrace();  
            throw new RuntimeException(e);  
        }  
    }  
  
    /** 
     * 移除一个任务(使用默认的任务组名，触发器名，触发器组名) 
     * 
     * @param jobName 
     */  
    public static void removeJob(String jobName) {  
        try {  
              Scheduler sched = gSchedulerFactory.getScheduler();  
              JobKey jobKey = JobKey.jobKey(jobName, JOB_GROUP_NAME);
              TriggerKey triggerKey = TriggerKey.triggerKey(jobName,TRIGGER_GROUP_NAME);
              sched.pauseTrigger(triggerKey);
              sched.unscheduleJob(triggerKey);
              sched.deleteJob(jobKey);
        } catch (Exception e) {  
            e.printStackTrace();  
            throw new RuntimeException(e);  
        }  
    }  
  
    /** 
     * 移除一个任务 
     * 
     * @param jobName 
     * @param jobGroupName 
     * @param triggerName 
     * @param triggerGroupName 
     */  
    public static void removeJob(String jobName, String jobGroupName,  
            String triggerName, String triggerGroupName) {  
        try {  
            Scheduler sched = gSchedulerFactory.getScheduler();  
            JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
            TriggerKey triggerKey = TriggerKey.triggerKey(jobName,triggerGroupName);
            sched.pauseTrigger(triggerKey);
            sched.unscheduleJob(triggerKey);
            sched.deleteJob(jobKey);
        } catch (Exception e) {  
            e.printStackTrace();  
            throw new RuntimeException(e);  
        }  
    }  
    
    /***
     * 立即执行，执行一次 使用默认分组
     * @param jobName
     */
    public static boolean runJob(String jobName){
    	boolean b = false;
		try {
			Scheduler sched = gSchedulerFactory.getScheduler();
			JobKey jobKey = JobKey.jobKey(jobName, JOB_GROUP_NAME);
	    	sched.triggerJob(jobKey);
	    	b = true;
		} catch (SchedulerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			b = false;
			throw new RuntimeException(e);
		}  
		return b;
    }
    
    /***
     * 立即执行，执行一次 制定分组
     * @param jobName
     */
    public static void runJob(String jobName,String jobGroupName){
		try {
			Scheduler sched = gSchedulerFactory.getScheduler();
			JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
	    	sched.triggerJob(jobKey);
		} catch (SchedulerException e) {
			// TODO Auto-generated catch block
			 e.printStackTrace();  
	         throw new RuntimeException(e);  
		}  
    }
    
    /***
     * 暂停任务 默认使用分组
     * @param jobName
     */
    public static void pauseJob(String jobName){
    	try {
			Scheduler scheduler = gSchedulerFactory.getScheduler();
			JobKey jobKey = JobKey.jobKey(jobName, JOB_GROUP_NAME);
			scheduler.pauseJob(jobKey);
		} catch (SchedulerException e) {
			// TODO Auto-generated catch block
			 e.printStackTrace();  
	         throw new RuntimeException(e);  
		}
    }
    
    /***
     * 暂停任务 指定分组
     * @param jobName
     */
    public static void pauseJob(String jobName,String jobGroupName){
    	try {
			Scheduler scheduler = gSchedulerFactory.getScheduler();
			JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
			scheduler.pauseJob(jobKey);
		} catch (SchedulerException e) {
			// TODO Auto-generated catch block
			 e.printStackTrace();  
	         throw new RuntimeException(e);  
		}
    }
    /***
     * 恢复任务 指定分组
     * @param jobName
     */
    public static void resumeJob(String jobName,String jobGroupName){
    	try {
			Scheduler scheduler = gSchedulerFactory.getScheduler();
			JobKey jobKey = JobKey.jobKey(jobName,jobGroupName);
			scheduler.resumeJob(jobKey);
		} catch (SchedulerException e) {
			// TODO Auto-generated catch block
			 e.printStackTrace();  
	         throw new RuntimeException(e);  
		}
    }
    /***
     * 恢复任务 默认分组
     * @param jobName
     */
    public static void resumeJob(String jobName){
    	try {
			Scheduler scheduler = gSchedulerFactory.getScheduler();
			JobKey jobKey = JobKey.jobKey(jobName);
			scheduler.resumeJob(jobKey);
		} catch (SchedulerException e) {
			// TODO Auto-generated catch block
			 e.printStackTrace();  
	         throw new RuntimeException(e);  
		}
    }
    /** 
     * 启动所有定时任务 
     */  
    public static void startJobs() {  
        try {  
            Scheduler sched = gSchedulerFactory.getScheduler();  
            if(sched.isShutdown()){
            	sched.start();  
            }
        } catch (Exception e) {  
            e.printStackTrace();  
            throw new RuntimeException(e);  
        }  
    }  
  
    /** 
     * 关闭所有定时任务 
     */  
    public static void shutdownJobs() {  
        try {  
            Scheduler sched = gSchedulerFactory.getScheduler();  
            if(!sched.isShutdown()) {  
                sched.shutdown();  
            }  
        } catch (Exception e) {  
            e.printStackTrace();  
            throw new RuntimeException(e);  
        }  
    }
    /**
     * 启动爬虫定时任务
     */
	@Override
	public boolean start() {
		// TODO Auto-generated method stub
		List<Tmagic> magic = Tmagic.dao.getAll();
		if(magic != null && magic.size() >0){
			for(Tmagic t:magic){
				//1开启定时任务,0为开启
				if("1".equals(t.getFstats())){
					Redis.use(CacheConsts.CACHE_QUARTZ_NAME).set(CacheConsts.CACHE_QUARTZ_NAME+":"+t.getFpage(), t.toJson());
					addJob(t.getFpage(),JOB_GROUP_GAME,t.getFpage(),TRIGGER_GROUP_GAME_NAME,t.getFclass(),t.getFcycle());
				}
				if("2".equals(t.getFstats())){
					String cachename2 = CacheConsts.CACHE_QUARTZ_NAME;
					String name2 = cachename2+":"+t.getFpage();
					String value2 = t.toJson();
					WZGLUtils.setCache(cachename2, name2, value2);
					pauseJob(t.getFpage());
				}
			}
			startJobs();
		}
		return true;
	}

	@Override
	public boolean stop() {
		// TODO Auto-generated method stub
		shutdownJobs();
		return false;
	}  
}
